#include "USART1.h"
#include "ringbuffer.h"

#define DMA_RX_BUF_SIZE  2048
uint8_t USART1_DMA_RxBuf[DMA_RX_BUF_SIZE];    // DMA接收缓存

ringbuffer_t rx_ringbuffer;   // 环形缓冲区-接收
ringbuffer_t tx_ringbuffer;   // 环形缓冲区-发送

//PDMACH_TypeDef *HT_PDMA; // 记得在其他地方声明外设定义

//-----------------------------------------------------------------------------
// USART1初始化
void USART1_Configuration(void)
{
  USART_InitTypeDef USART_InitStruct;
  CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
  PDMACH_InitTypeDef PDMA_InitStruct;

  CKCUClock.Bit.USART1 = 1;
  CKCUClock.Bit.AFIO   = 1;
  CKCUClock.Bit.PDMA   = 1;
  CKCUClock.Bit.PA     = 1;
  CKCU_PeripClockConfig(CKCUClock, ENABLE);

  GPIO_PullResistorConfig(HT_GPIOA, GPIO_PIN_5, GPIO_PR_UP);
  AFIO_GPxConfig(GPIO_PA, AFIO_PIN_4, AFIO_FUN_USART_UART);
  AFIO_GPxConfig(GPIO_PA, AFIO_PIN_5, AFIO_FUN_USART_UART);

  USART_InitStruct.USART_BaudRate = 115200;
  USART_InitStruct.USART_WordLength = USART_WORDLENGTH_8B;
  USART_InitStruct.USART_StopBits = USART_STOPBITS_1;
  USART_InitStruct.USART_Parity = USART_PARITY_NO;
  USART_InitStruct.USART_Mode = USART_MODE_NORMAL;
  USART_Init(HT_USART1, &USART_InitStruct);

  USART_TxCmd(HT_USART1, ENABLE);
  USART_RxCmd(HT_USART1, ENABLE);

  /* DMA配置 */
  PDMA_InitStruct.PDMACH_SrcAddr   = (u32)&HT_USART1->DR;
  PDMA_InitStruct.PDMACH_DstAddr   = (u32)USART1_DMA_RxBuf;
  PDMA_InitStruct.PDMACH_BlkCnt    = 1;
  PDMA_InitStruct.PDMACH_BlkLen    = DMA_RX_BUF_SIZE;
  PDMA_InitStruct.PDMACH_DataSize  = WIDTH_8BIT;
  PDMA_InitStruct.PDMACH_Priority  = M_PRIO;
  PDMA_InitStruct.PDMACH_AdrMod    = SRC_ADR_FIX | DST_ADR_LIN_INC;
  PDMA_Config(PDMA_CH3, &PDMA_InitStruct);

  PDMA_IntConfig(PDMA_CH3, PDMA_INT_TC, ENABLE);
  PDMA_EnaCmd(PDMA_CH3, ENABLE);

  USART_PDMACmd(HT_USART1, USART_PDMAREQ_RX, ENABLE);

  /* 初始化环形缓冲区 */
  ringbuffer_init(&rx_ringbuffer);
  ringbuffer_init(&tx_ringbuffer);

  /* 开启USART中断（只开启发送完成中断） */
  NVIC_EnableIRQ(USART1_IRQn);
}

//-----------------------------------------------------------------------------
// USART1 中断函数
void USART1_IRQHandler(void)
{
  // Tx中断，发送环形缓冲区数据
  if (USART_GetIntStatus(HT_USART1, USART_INT_TXC) != RESET)
  {
    if (ringbuffer_is_empty(&tx_ringbuffer))
    {
      USART_IntConfig(HT_USART1, USART_INT_TXC, DISABLE); // 发送完了，关中断
    }
    else
    {
      uint8_t data;
      ringbuffer_read(&tx_ringbuffer, &data, 1);
      USART_SendData(HT_USART1, data);
    }
  }
}

//-----------------------------------------------------------------------------
// PDMA 中断（接收完成）
void PDMA_IRQHandler(void)
{
  if (PDMA_GetFlagStatus(PDMA_CH3, PDMA_FLAG_TC) != RESET)
  {
    PDMA_ClearFlag(PDMA_CH3, PDMA_FLAG_TC);

    /* 将DMA缓存区数据复制到接收环形缓冲区 */
    for (uint16_t i = 0; i < DMA_RX_BUF_SIZE; i++)
    {
      ringbuffer_write(&rx_ringbuffer, &USART1_DMA_RxBuf[i], 1);
    }

    /* 重新启动DMA接收 */
    PDMA_EnaCmd(PDMA_CH3, ENABLE);
  }
}

//-----------------------------------------------------------------------------
// 发送一组数据（通过环形缓冲区）
void USART1_tx_data(uint8_t *pt, uint16_t len)
{
  ringbuffer_write(&tx_ringbuffer, pt, len);

  /* 确保发送中断开启 */
  USART_IntConfig(HT_USART1, USART_INT_TXC, ENABLE);
}

//-----------------------------------------------------------------------------
// 分析接收数据（你可以自己改）
void USART1_analyze_data(void)
{
  uint8_t tmp;

  if (ringbuffer_is_empty(&rx_ringbuffer))
    return;

  ringbuffer_read(&rx_ringbuffer, &tmp, 1);

  if (tmp != 0xAA)
  {
    return; // 丢弃非法数据
  }
  else if (rx_ringbuffer.itemCount >= 8)
  {
    // 可以进一步读取处理
  }
}

